home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / SATAN11.ZIP / SRC / RPCGEN / RPC_SCAN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-08  |  8.7 KB  |  485 lines

  1. /* @(#)rpc_scan.c    2.1 88/08/01 4.0 RPCSRC */
  2. /*
  3.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  4.  * unrestricted use provided that this legend is included on all tape
  5.  * media and as a part of the software program in whole or part.  Users
  6.  * may copy or modify Sun RPC without charge, but are not authorized
  7.  * to license or distribute it to anyone else except as part of a product or
  8.  * program developed by the user.
  9.  * 
  10.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  11.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  12.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  13.  * 
  14.  * Sun RPC is provided with no support and without any obligation on the
  15.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  16.  * modification or enhancement.
  17.  * 
  18.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  19.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  20.  * OR ANY PART THEREOF.
  21.  * 
  22.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  23.  * or profits or other special, indirect and consequential damages, even if
  24.  * Sun has been advised of the possibility of such damages.
  25.  * 
  26.  * Sun Microsystems, Inc.
  27.  * 2550 Garcia Avenue
  28.  * Mountain View, California  94043
  29.  */
  30. #ifndef lint
  31. static char sccsid[] = "@(#)rpc_scan.c 1.6 87/06/24 (C) 1987 SMI";
  32. #endif
  33.  
  34. /*
  35.  * rpc_scan.c, Scanner for the RPC protocol compiler 
  36.  * Copyright (C) 1987, Sun Microsystems, Inc. 
  37.  */
  38. #include <stdio.h>
  39. #include <ctype.h>
  40. #include <stdlib.h>
  41. #include <unistd.h>
  42. #include <string.h>
  43. #include "rpc_scan.h"
  44. #include "rpc_util.h"
  45.  
  46. #define startcomment(where) (where[0] == '/' && where[1] == '*')
  47. #define endcomment(where) (where[-1] == '*' && where[0] == '/')
  48.  
  49. static int pushed = 0;    /* is a token pushed */
  50. static token lasttok;    /* last token, if pushed */
  51.  
  52. static unget_token();
  53. static findstrconst();
  54. static findconst();
  55. static findkind();
  56. static cppline();
  57. static directive();
  58. static printdirective();
  59. static docppline();
  60.  
  61. /*
  62.  * scan expecting 1 given token 
  63.  */
  64. void
  65. scan(expect, tokp)
  66.     tok_kind expect;
  67.     token *tokp;
  68. {
  69.     get_token(tokp);
  70.     if (tokp->kind != expect) {
  71.         expected1(expect);
  72.     }
  73. }
  74.  
  75. /*
  76.  * scan expecting 2 given tokens 
  77.  */
  78. void
  79. scan2(expect1, expect2, tokp)
  80.     tok_kind expect1;
  81.     tok_kind expect2;
  82.     token *tokp;
  83. {
  84.     get_token(tokp);
  85.     if (tokp->kind != expect1 && tokp->kind != expect2) {
  86.         expected2(expect1, expect2);
  87.     }
  88. }
  89.  
  90. /*
  91.  * scan expecting 3 given token 
  92.  */
  93. void
  94. scan3(expect1, expect2, expect3, tokp)
  95.     tok_kind expect1;
  96.     tok_kind expect2;
  97.     tok_kind expect3;
  98.     token *tokp;
  99. {
  100.     get_token(tokp);
  101.     if (tokp->kind != expect1 && tokp->kind != expect2
  102.         && tokp->kind != expect3) {
  103.         expected3(expect1, expect2, expect3);
  104.     }
  105. }
  106.  
  107.  
  108. /*
  109.  * scan expecting a constant, possibly symbolic 
  110.  */
  111. void
  112. scan_num(tokp)
  113.     token *tokp;
  114. {
  115.     get_token(tokp);
  116.     switch (tokp->kind) {
  117.     case TOK_IDENT:
  118.         break;
  119.     default:
  120.         error("constant or identifier expected");
  121.     }
  122. }
  123.  
  124.  
  125. /*
  126.  * Peek at the next token 
  127.  */
  128. void
  129. peek(tokp)
  130.     token *tokp;
  131. {
  132.     get_token(tokp);
  133.     unget_token(tokp);
  134. }
  135.  
  136.  
  137. /*
  138.  * Peek at the next token and scan it if it matches what you expect 
  139.  */
  140. int
  141. peekscan(expect, tokp)
  142.     tok_kind expect;
  143.     token *tokp;
  144. {
  145.     peek(tokp);
  146.     if (tokp->kind == expect) {
  147.         get_token(tokp);
  148.         return (1);
  149.     }
  150.     return (0);
  151. }
  152.  
  153.  
  154.  
  155. /*
  156.  * Get the next token, printing out any directive that are encountered. 
  157.  */
  158. void
  159. get_token(tokp)
  160.     token *tokp;
  161. {
  162.     int commenting;
  163.  
  164.     if (pushed) {
  165.         pushed = 0;
  166.         *tokp = lasttok;
  167.         return;
  168.     }
  169.     commenting = 0;
  170.     for (;;) {
  171.         if (*where == 0) {
  172.             for (;;) {
  173.                 if (!fgets(curline, MAXLINESIZE, fin)) {
  174.                     tokp->kind = TOK_EOF;
  175.                     *where = 0;
  176.                     return;
  177.                 }
  178.                 linenum++;
  179.                 if (commenting) {
  180.                     break;
  181.                 } else if (cppline(curline)) {
  182.                     docppline(curline, &linenum, 
  183.                           &infilename);
  184.                 } else if (directive(curline)) {
  185.                     printdirective(curline);
  186.                 } else {
  187.                     break;
  188.                 }
  189.             }
  190.             where = curline;
  191.         } else if (isspace(*where)) {
  192.             while (isspace(*where)) {
  193.                 where++;    /* eat */
  194.             }
  195.         } else if (commenting) {
  196.             where++;
  197.             if (endcomment(where)) {
  198.                 where++;
  199.                 commenting--;
  200.             }
  201.         } else if (startcomment(where)) {
  202.             where += 2;
  203.             commenting++;
  204.         } else {
  205.             break;
  206.         }
  207.     }
  208.  
  209.     /*
  210.      * 'where' is not whitespace, comment or directive Must be a token! 
  211.      */
  212.     switch (*where) {
  213.     case ':':
  214.         tokp->kind = TOK_COLON;
  215.         where++;
  216.         break;
  217.     case ';':
  218.         tokp->kind = TOK_SEMICOLON;
  219.         where++;
  220.         break;
  221.     case ',':
  222.         tokp->kind = TOK_COMMA;
  223.         where++;
  224.         break;
  225.     case '=':
  226.         tokp->kind = TOK_EQUAL;
  227.         where++;
  228.         break;
  229.     case '*':
  230.         tokp->kind = TOK_STAR;
  231.         where++;
  232.         break;
  233.     case '[':
  234.         tokp->kind = TOK_LBRACKET;
  235.         where++;
  236.         break;
  237.     case ']':
  238.         tokp->kind = TOK_RBRACKET;
  239.         where++;
  240.         break;
  241.     case '{':
  242.         tokp->kind = TOK_LBRACE;
  243.         where++;
  244.         break;
  245.     case '}':
  246.         tokp->kind = TOK_RBRACE;
  247.         where++;
  248.         break;
  249.     case '(':
  250.         tokp->kind = TOK_LPAREN;
  251.         where++;
  252.         break;
  253.     case ')':
  254.         tokp->kind = TOK_RPAREN;
  255.         where++;
  256.         break;
  257.     case '<':
  258.         tokp->kind = TOK_LANGLE;
  259.         where++;
  260.         break;
  261.     case '>':
  262.         tokp->kind = TOK_RANGLE;
  263.         where++;
  264.         break;
  265.  
  266.     case '"':
  267.         tokp->kind = TOK_STRCONST;
  268.         findstrconst(&where, &tokp->str);
  269.         break;
  270.  
  271.     case '-':
  272.     case '0':
  273.     case '1':
  274.     case '2':
  275.     case '3':
  276.     case '4':
  277.     case '5':
  278.     case '6':
  279.     case '7':
  280.     case '8':
  281.     case '9':
  282.         tokp->kind = TOK_IDENT;
  283.         findconst(&where, &tokp->str);
  284.         break;
  285.  
  286.  
  287.     default:
  288.         if (!(isalpha(*where) || *where == '_')) {
  289.             char buf[100];
  290.             char *p;
  291.  
  292.             s_print(buf, "illegal character in file: ");
  293.             p = buf + strlen(buf);
  294.             if (isprint(*where)) {
  295.                 s_print(p, "%c", *where);
  296.             } else {
  297.                 s_print(p, "%d", *where);
  298.             }
  299.             error(buf);
  300.         }
  301.         findkind(&where, tokp);
  302.         break;
  303.     }
  304. }
  305.  
  306.  
  307.  
  308. static
  309. unget_token(tokp)
  310.     token *tokp;
  311. {
  312.     lasttok = *tokp;
  313.     pushed = 1;
  314. }
  315.  
  316.  
  317. static
  318. findstrconst(str, val)
  319.     char **str;
  320.     char **val;
  321. {
  322.     char *p;
  323.     int size;
  324.  
  325.     p = *str;
  326.     do {
  327.         *p++;
  328.     } while (*p && *p != '"');
  329.     if (*p == 0) {
  330.         error("unterminated string constant");
  331.     }
  332.     p++;
  333.     size = p - *str;
  334.     *val = alloc(size + 1);
  335.     (void) strncpy(*val, *str, size);
  336.     (*val)[size] = 0;
  337.     *str = p;
  338. }
  339.  
  340. static
  341. findconst(str, val)
  342.     char **str;
  343.     char **val;
  344. {
  345.     char *p;
  346.     int size;
  347.  
  348.     p = *str;
  349.     if (*p == '0' && *(p + 1) == 'x') {
  350.         p++;
  351.         do {
  352.             p++;
  353.         } while (isxdigit(*p));
  354.     } else {
  355.         do {
  356.             p++;
  357.         } while (isdigit(*p));
  358.     }
  359.     size = p - *str;
  360.     *val = alloc(size + 1);
  361.     (void) strncpy(*val, *str, size);
  362.     (*val)[size] = 0;
  363.     *str = p;
  364. }
  365.  
  366.  
  367.  
  368. static token symbols[] = {
  369.               {TOK_CONST, "const"},
  370.               {TOK_UNION, "union"},
  371.               {TOK_SWITCH, "switch"},
  372.               {TOK_CASE, "case"},
  373.               {TOK_DEFAULT, "default"},
  374.               {TOK_STRUCT, "struct"},
  375.               {TOK_TYPEDEF, "typedef"},
  376.               {TOK_ENUM, "enum"},
  377.               {TOK_OPAQUE, "opaque"},
  378.               {TOK_BOOL, "bool"},
  379.               {TOK_VOID, "void"},
  380.               {TOK_CHAR, "char"},
  381.               {TOK_INT, "int"},
  382.               {TOK_UNSIGNED, "unsigned"},
  383.               {TOK_SHORT, "short"},
  384.               {TOK_LONG, "long"},
  385.               {TOK_FLOAT, "float"},
  386.               {TOK_DOUBLE, "double"},
  387.               {TOK_STRING, "string"},
  388.               {TOK_PROGRAM, "program"},
  389.               {TOK_VERSION, "version"},
  390.               {TOK_EOF, "??????"},
  391. };
  392.  
  393.  
  394. static
  395. findkind(mark, tokp)
  396.     char **mark;
  397.     token *tokp;
  398. {
  399.  
  400.     int len;
  401.     token *s;
  402.     char *str;
  403.  
  404.     str = *mark;
  405.     for (s = symbols; s->kind != TOK_EOF; s++) {
  406.         len = strlen(s->str);
  407.         if (strncmp(str, s->str, len) == 0) {
  408.             if (!isalnum(str[len]) && str[len] != '_') {
  409.                 tokp->kind = s->kind;
  410.                 tokp->str = s->str;
  411.                 *mark = str + len;
  412.                 return;
  413.             }
  414.         }
  415.     }
  416.     tokp->kind = TOK_IDENT;
  417.     for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
  418.     tokp->str = alloc(len + 1);
  419.     (void) strncpy(tokp->str, str, len);
  420.     tokp->str[len] = 0;
  421.     *mark = str + len;
  422. }
  423.  
  424. static
  425. cppline(line)
  426.     char *line;
  427. {
  428.     return (line == curline && *line == '#');
  429. }
  430.  
  431. static
  432. directive(line)
  433.     char *line;
  434. {
  435.     return (line == curline && *line == '%');
  436. }
  437.  
  438. static
  439. printdirective(line)
  440.     char *line;
  441. {
  442.     f_print(fout, "%s", line + 1);
  443. }
  444.  
  445. static
  446. docppline(line, lineno, fname)
  447.     char *line;
  448.     int *lineno;
  449.     char **fname;
  450. {
  451.     char *file;
  452.     int num;
  453.     char *p;
  454.  
  455.     line++;
  456.     while (isspace(*line)) {
  457.         line++;
  458.     }
  459.     num = atoi(line);
  460.     while (isdigit(*line)) {
  461.         line++;
  462.     }
  463.     while (isspace(*line)) {
  464.         line++;
  465.     }
  466.     if (*line != '"') {
  467.         error("preprocessor error");
  468.     }
  469.     line++;
  470.     p = file = alloc(strlen(line) + 1);
  471.     while (*line && *line != '"') {
  472.         *p++ = *line++;
  473.     }
  474.     if (*line == 0) {
  475.         error("preprocessor error");
  476.     }
  477.     *p = 0;
  478.     if (*file == 0) {
  479.         *fname = NULL;
  480.     } else {
  481.         *fname = file;
  482.     }
  483.     *lineno = num - 1;
  484. }
  485.